/**
 * @file tiny_thread.h
 * @author 张恒宣 
 * @LastEditTime 2025/4/06
 * 
 * MIT License
 *
 * Copyright (c) 2025 张恒宣 luckkeymail@163.com
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#ifndef __TINY_THREAD_H__
#define __TINY_THREAD_H__

/*********************
 *       头文件
 *********************/

#include "tiny_def.h"
#include "tiny_list.h"
#include "tiny_timer.h"

/**********************
 *       宏定义
 **********************/

#define TINY_THREAD_MAX_PRIORITY 32

#define TINY_THREAD_ENTRY(ptr) \
	STRUCT_TRANCING_PARENT(ptr, tiny_thread_t, list_node_link)

/**********************
 *      类型定义
 **********************/

typedef void (*thread_callback_t)(void *);
typedef void *tiny_thread_hander;

typedef enum
{
	THREAD_READY,
	THREAD_SUSPEND,
	THREAD_BLOCKED,
	THREAD_RUNNING,
	THREAD_DEAD,
} thread_statu_t;

typedef enum
{
	THREAD_BLOCK_TIMEOUT = 0,
	THREAD_BLOCK_NOT_TIMEOUT
} THREAD_BLOCK_RET;

typedef struct
{
	tiny_uint32_t r0;
	tiny_uint32_t r1;
	tiny_uint32_t r2;
	tiny_uint32_t r3;
	tiny_uint32_t r12;
	tiny_uint32_t lr;
	tiny_uint32_t pc;
	tiny_uint32_t xpsr;
} env_register_t;

typedef struct
{
	tiny_uint32_t r4;
	tiny_uint32_t r5;
	tiny_uint32_t r6;
	tiny_uint32_t r7;
	tiny_uint32_t r8;
	tiny_uint32_t r9;
	tiny_uint32_t r10;
	tiny_uint32_t r11;
	env_register_t env_reg;
} tiny_tcb_t;

typedef struct
{
	const tiny_int8_t *name;
	tiny_uint32_t tid;
	tiny_uint32_t sp;
	tiny_uint8_t *stack;
	tiny_uint32_t statck_size;
	tiny_uint32_t init_tick;
	tiny_uint32_t remain_tick;
	tiny_uint32_t min_remain_stack;
	
#if IS_OPEN_GET_CPU == PROFILE_OPEN
	tiny_uint64_t schedule_last_tick;
	tiny_uint64_t run_time;
	float cpu_usage;
#endif
	
	tiny_uint32_t init_priority;
	tiny_uint32_t cur_priority;
	tiny_list_node_t list_node_link;
	tiny_list_node_t list_all_thread_link;
	tiny_timer_t timer;
	thread_callback_t exit_hook;
	void* exit_hook_param;
	THREAD_BLOCK_RET timer_ret;
	thread_statu_t statu;
	tiny_uint8_t no_used[2];
	
} tiny_thread_t;


/**********************
 *       函数声明
 **********************/

tiny_thread_hander tiny_thread_create(const char *name, tiny_uint32_t stack_size, tiny_uint32_t priority, thread_callback_t entry_callback, void *param);
void tiny_thread_startup(tiny_thread_hander thread);
tiny_thread_hander get_self_thread(void);
void tiny_kill_thread(tiny_thread_hander hander);
void tiny_thread_kill_self(void);
tiny_thread_hander tiny_wakeap_one_list_thread(tiny_list_t *list, tiny_ret_status_t is_shedule);
void tiny_wakeup_all_list_thread(tiny_list_t *list);
void tiny_suspend_thread(tiny_thread_hander hander);
void tiny_resume_thread(tiny_thread_hander hander);
tiny_int32_t tiny_suspend_thread_in_dst_list(tiny_thread_hander hander, tiny_list_t *dst_list);
void tiny_thread_delay_tick(tiny_int32_t tick);
void tiny_thread_delay_ms(tiny_int32_t ms);
void tiny_thread_set_cur_priority(tiny_thread_hander thread, tiny_uint32_t priority);
void tiny_thread_resume_init_priority(tiny_thread_hander thread);
void tiny_yield(void);
void tiny_open_schedule(void);
void tiny_close_schedule(void);
tiny_int8_t tiny_get_schedule(void);
void schedule(void);
tiny_uint64_t tiny_get_tick_count(void);
void tiny_kernel_system_tick(void);
tiny_ret_status_t tiny_kernel_startup(void);
void tiny_thread_set_exit_hook(tiny_thread_hander thread, thread_callback_t exit_callback, void* param);
void tiny_list_thread(void (*callback)(tiny_thread_t *));
tiny_uint32_t tiny_thread_get_min_remaining_stack(tiny_thread_hander thread);
int tiny_find_high_ready_priority(void);
tiny_thread_t* tiny_get_thread_by_tid(tiny_uint32_t tid);

#if IS_OPEN_GET_CPU == PROFILE_OPEN
tiny_uint64_t tiny_thread_get_thread_run_time(tiny_thread_hander thread);
void tiny_thread_clear_thread_run_time(tiny_thread_hander thread);
tiny_uint64_t tiny_thread_get_all_thread_run_time(void);
void tiny_thread_clear_all_thread_run_time(void);
float tiny_thread_get_cpu_usage(tiny_thread_hander thread);
#endif

#if IS_OPEN_STACK_HIGH_WATER == PROFILE_OPEN
tiny_uint32_t tiny_thread_get_stack_high_water(tiny_thread_hander thread);
#endif

/**********************
 *       内联函数
 **********************/

/// @brief 获得线程状态字符串.
/// @param status 线程状态
inline static const char* tiny_thread_status2str(thread_statu_t status)
{
	static const char* thread_status[] = {"READY", "SUSPEND", "BLOCKED", "RUNNING", "DEAD"};
	if (status > THREAD_DEAD)
		return "Not Know";
	
	return thread_status[status];
}


#endif //!__TINY_THREAD_H__
